package com.bw.mvi.mvi

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.bw.mvi.api.BaseApiService
import com.bw.mvi.http.OkHttpClientManager.createRetrofit
import com.example.common.entity.BaseResponse
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.lang.reflect.ParameterizedType

/**
 * 基础ViewModel
 */
abstract class BaseViewModel<API : BaseApiService,uiIntent : UiIntent>:ViewModel() {


    private val type by lazy { (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments }
    protected val apiService: API by lazy {
        val clazz = type[0] as Class<API>
        createRetrofit().create(clazz)
    }


    private val channel = Channel<uiIntent> { Channel.UNLIMITED }

    private val _state = MutableStateFlow<UiState>(UiState.onLoading)
    val state: StateFlow<UiState>
        get() = _state




    abstract fun handleIntent(intent: uiIntent)

    init {
        viewModelScope.launch {
            channel.receiveAsFlow().collect {
                handleIntent(it)
            }
        }
    }



    fun sendIntent(intent: uiIntent) {
        viewModelScope.launch {
            channel.send(intent)
        }
    }

    fun httpRequest(request: Flow<BaseResponse<*>>, type: String) {
        viewModelScope.launch {
            request.flowOn(Dispatchers.IO)
                .catch { Log.e("TagA", "httpRequest: ${it.message}") }
                .collect {
                    if (it.code == 0 || it.code == 200) {
                        _state.value = UiState.onSuccess(it.data,type)
                    } else {
                        _state.value = UiState.onError(it.msg)
                    }
                }
        }
    }
    fun <T> roomRequest(s: suspend () -> T, type: String) {
        viewModelScope.launch {
            flow { emit(s.invoke()) }.flowOn(Dispatchers.IO)
                .catch { Log.e("TagA", "roomRequest: ${it.message}") }
                .collect {
                    if (it != null) {
                        _state.value = UiState.onSuccess(it, type)
                    } else {
                        _state.value = UiState.onError("数据库错误")
                    }
                }
        }
    }
}
